﻿using System;
using System.Collections.Generic;
using Jayden.Dll.Web.HtmlControls.Descriptions;
using Jayden.Dll.Web.HtmlControls.Generics;
using Jayden.Dll.Web.Scripts;
using Jayden.Dll.Web.Styles;

namespace Jayden.Dll.Web.HtmlControls
{
	public class Head : HtmlElement
	{
		public Head() : base(HeadDescription.Instance) { }

		public new Title Title
		{
			get
			{
				List<Title> titles = new List<Title>(GetControls<Title>());
				if (titles.Count == 1)
					return titles[0];
				return null;
			}
		}
		public Link AddLink() { return AddControl(new Link()) as Link; }
		public Link AddLinkCss(string href)
		{
			Link link = AddLink();
			link.Rel = CssHelper.LinkRel;
			link.Type = CssHelper.MimeType;
			link.HRef = href;
			return link;
		}
		public bool ContainsLinkCss(string href)
		{
			if(m_ChildControls != null && m_ChildControls.Count> 0)
				foreach (HtmlControl control in m_ChildControls)
				{
					Link link = control as Link;
					if (link != null && link.Rel == CssHelper.LinkRel && link.Type == CssHelper.MimeType && link.HRef == href)
						return true;
				}
			return false;
		}
		public Script AddScript() { return AddControl(new Script()) as Script; }
		public Script AddScriptJs(string src)
		{
			Script script = AddScript();
			script.Type = JsHelper.MimeType;
			script.Src = src;
			return script;
		}
		public bool ContainsScriptJs(string src)
		{
			if (m_ChildControls != null && m_ChildControls.Count > 0)
				foreach (HtmlControl control in m_ChildControls)
				{
					Script script = control as Script;
					if (script != null && script.Type == JsHelper.MimeType && script.Src == src)
						return true;
				}
			return false;
		}
		public Meta AddMeta() { return AddControl(new Meta()) as Meta; }
		public Meta AddMetaName(string name, string content)
		{
			Meta meta = AddMeta();
			meta.Name = name;
			meta.Content = content;
			return meta;
		}
		public bool ContainsMetaName(string name)
		{
			if (m_ChildControls != null && m_ChildControls.Count > 0)
				foreach (HtmlControl control in m_ChildControls)
				{
					Meta meta = control as Meta;
					if (meta != null && meta.Name == name)
						return true;
				}
			return false;
		}
		public Meta AddMetaHttpEquiv(string httpEquiv, string content)
		{
			Meta meta = AddMeta();
			meta.HttpEquiv = httpEquiv;
			meta.Content = content;
			return meta;
		}
		public bool ContainsMetaHttpEquiv(string httpEquiv)
		{
			if (m_ChildControls != null && m_ChildControls.Count > 0)
				foreach (HtmlControl control in m_ChildControls)
				{
					Meta meta = control as Meta;
					if (meta != null && meta.HttpEquiv == httpEquiv)
						return true;
				}
			return false;
		}
		public Base Base { get { return GetElementByTagName<Base>("base"); } }
	}
	public class HeadDescription : HtmlElementDescription
	{
		public static readonly HeadDescription Instance = new HeadDescription();
		private HeadDescription() : base("head") { }
		public override Type ControlType { get { return typeof(Head); } }
		public override string Description { get { return "collects the document’s metadata."; } }
		public override bool AllowInnerText { get { return false; } }
		public override bool AllowPhrasingContent { get { return true; } }
		public override IEnumerable<HtmlElementDescription> PermittedParents { get { yield return HtmlDescription.Instance; } }
		public override IEnumerable<HtmlElementDescription> PermittedElements
		{
			get
			{
				yield return TitleDescription.Instance;
				yield return MetaDescription.Instance;
				yield return ScriptDescription.Instance;
				yield return LinkDescription.Instance;
				yield return StyleDescription.Instance;
			}
		}

		public override bool CheckValidity(HtmlControl control)
		{
			if (base.CheckValidity(control))
			{
				Head head = control as Head;
				int title = 0;
				int baseElt = 0;
				foreach (HtmlControl child in head.ChildControls)
				{
					if (child is Title)
					{
						if (title > 0)
							throw new Exception("only one <title> is allowed.");
						title++;
					}
					else if (child is Base)
					{
						if (baseElt > 0)
							throw new Exception("only one <base> is allowed.");
						baseElt++;
					}
				}
				return true;
			}
			return false;
		}
	}
}
